home *** CD-ROM | disk | FTP | other *** search
- From: wietse@wzv.win.tue.nl (Wietse Venema)
- Newsgroups: alt.security,alt.sources,comp.sys.sun.admin
- Subject: fixing the LD_LIBRARY_PATH problem (source)
- Keywords: SunOS, sync, breakins, passwords
- Message-ID: <2902@wzv.win.tue.nl>
- Date: 31 Jan 92 21:01:12 GMT
- References: <799@itexjct.jct.ac.il> <5317@stl.co.uk> <1992Jan28.133241.17998@cccan.uucp> <v70r=af@rpi.edu>
- Organization: Eindhoven University of Technology, The Netherlands
-
- Recent articles in alt.security discuss the possibilities to introduce
- trojan horses via the SunOS 4.x LD_LIBRARY_PATH environment variable.
-
- Examples involve the password-less "sync" account. By default, it has
- the same uid as the "daemon" account, which is the owner of the printer
- spooling subsystem. The "login -p" (preserve environment) and "su"
- (without switches) commands can both be used for this purpose.
-
- Getting rid of password-less accounts (or giving them a unique user id
- that does not own any files) does help, but it does not eliminate the
- underlying problems. These problems are tied to the way LD_LIBRARY_PATH
- interacts with commands such as "login" and "su".
-
- Some background: according to the SunOS 4.x ld.so manual page, the
- LD_LIBRARY_PATH variable is ignored with set-uid programs (effective
- uid != real uid). This is a good idea with programs like "login" and
- "su", but it solves only part of the problem. Reason: both commands
- set the effective and real uids to the same value, thus making their
- offspring susceptible to LD_LIBRARY_PATH tricks.
-
- My conclusion is that commands like "login" and "su" should not pass on
- any LD_LIBRARY_PATH information. The "login" command is easily fixed:
- the following step has already been suggested in other articles:
-
- - Disable world-execute permission on /usr/bin/login, so that the
- "-p" option (preserve environment) can no longer be abused.
-
- Revoking world-execute permission of the "su" command is not productive.
- The following steps are more practical:
-
- - Run a modified /usr/bin/su that clears LD_LIBRARY_PATH (see source
- attached to the end of this article).
-
- - Delete /usr/5bin/su. With SunOS 4.1.1, it gives root a path with
- "." at the front, which is totally ridiculous anyway.
-
- My SunOS 4.x "su" replacement is in the form of patches to source from
- the latest BSD source release, available from ftp.uu.net (directory
- /packages/bsd-sources) and many other places, such as ftp.win.tue.nl
- (directory /pub/bsd-sources). The following files are required:
-
- .../bsd-sources/usr.bin/su/su.c.Z
- .../bsd-sources/lib/libc/stdlib/getenv.c.Z
- .../bsd-sources/lib/libc/stdlib/putenv.c.Z
- .../bsd-sources/lib/libc/string/strdup.c.Z
-
- The patch can be found in the attached shar file. The reader can easily
- verify that all it does is to change some messages to SunOS style, and
- to clean up the environment.
-
- Wietse
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of shell archive."
- # Contents: diffs Makefile
- # Wrapped by wietse@wzv on Fri Jan 31 21:19:01 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f diffs -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"diffs\"
- else
- echo shar: Extracting \"diffs\" \(2871 characters\)
- sed "s/^X//" >diffs <<'END_OF_diffs'
- X*** su.c- Fri Jan 31 13:42:53 1992
- X--- su.c Fri Jan 31 21:06:51 1992
- X***************
- X*** 48,56 ****
- X--- 48,66 ----
- X #include <stdio.h>
- X #include <pwd.h>
- X #include <grp.h>
- X+ #ifdef sun /* string stuff */
- X+ #include <strings.h>
- X+ char *strdup();
- X+ #else
- X #include <string.h>
- X+ #endif
- X #include <unistd.h>
- X+ #ifdef sun /* no <paths.h> file */
- X+ #define _PATH_BSHELL "/bin/sh"
- X+ #define _PATH_DEFPATH "/usr/bin:/usr/ucb"
- X+ #else
- X #include <paths.h>
- X+ #endif
- X
- X #ifdef KERBEROS
- X #include <kerberosIV/des.h>
- X***************
- X*** 114,120 ****
- X--- 124,132 ----
- X prio = getpriority(PRIO_PROCESS, 0);
- X if (errno)
- X prio = 0;
- X+ #ifndef sun /* do not muck with process priority */
- X (void)setpriority(PRIO_PROCESS, 0, -2);
- X+ #endif
- X openlog("su", LOG_CONS, 0);
- X
- X /* get current login name and shell */
- X***************
- X*** 153,159 ****
- X--- 165,175 ----
- X for (g = gr->gr_mem;; ++g) {
- X if (!*g) {
- X (void)fprintf(stderr,
- X+ #ifdef sun /* generate SunOS-like go-away message */
- X+ "You do not have permission to su root.\n",
- X+ #else
- X "su: you are not in the correct group to su %s.\n",
- X+ #endif
- X user);
- X exit(1);
- X }
- X***************
- X*** 166,173 ****
- X--- 182,194 ----
- X if (strcmp(pwd->pw_passwd, crypt(p, pwd->pw_passwd))) {
- X fprintf(stderr, "Sorry\n");
- X syslog(LOG_AUTH|LOG_WARNING,
- X+ #ifdef sun /* generate SunOS-like syslog messages */
- X+ "'su %s' failed for %s%s", user,
- X+ username, ontty());
- X+ #else
- X "BAD SU %s to %s%s", username,
- X user, ontty());
- X+ #endif
- X exit(1);
- X }
- X }
- X***************
- X*** 212,217 ****
- X--- 233,243 ----
- X exit(1);
- X }
- X
- X+ #ifdef sun /* Security: clear LD_LIBRARY_PATH, unless invoked by root. */
- X+ if (ruid)
- X+ unsetenv("LD_LIBRARY_PATH");
- X+ unsetenv("IFS"); /* Sheesh, what did Sun do with /usr/bin/sh... */
- X+ #endif
- X if (!asme) {
- X if (asthem) {
- X p = getenv("TERM");
- X***************
- X*** 240,250 ****
- X--- 266,283 ----
- X /* csh strips the first character... */
- X *np = asthem ? "-su" : iscsh == YES ? "_su" : "su";
- X
- X+ #ifdef sun /* generate SunOS-like syslog messages */
- X+ syslog(LOG_NOTICE|LOG_AUTH, "'su %s' succeeded for %s%s",
- X+ user, username, ontty());
- X+ #else
- X if (ruid != 0)
- X syslog(LOG_NOTICE|LOG_AUTH, "%s to %s%s",
- X username, user, ontty());
- X+ #endif
- X
- X+ #ifndef sun /* do not muck with process priority */
- X (void)setpriority(PRIO_PROCESS, 0, prio);
- X+ #endif
- X
- X execv(shell, np);
- X (void)fprintf(stderr, "su: %s not found.\n", shell);
- X*** strdup.c- Fri Jan 31 15:33:43 1992
- X--- strdup.c Fri Jan 31 15:47:42 1992
- X***************
- X*** 35,40 ****
- X--- 35,43 ----
- X static char sccsid[] = "@(#)strdup.c 5.4 (Berkeley) 2/24/91";
- X #endif /* LIBC_SCCS and not lint */
- X
- X+ #ifdef sun /* for u_int */
- X+ #include <sys/types.h>
- X+ #endif
- X #include <stddef.h>
- X #include <stdlib.h>
- X #include <string.h>
- END_OF_diffs
- if test 2871 -ne `wc -c <diffs`; then
- echo shar: \"diffs\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- if test -f Makefile -a "${1}" != "-c" ; then
- echo shar: Will not over-write existing file \"Makefile\"
- else
- echo shar: Extracting \"Makefile\" \(104 characters\)
- sed "s/^X//" >Makefile <<'END_OF_Makefile'
- XCFLAGS = -O -Dconst=
- XOBJS = su.o setenv.o getenv.o strdup.o
- X
- Xsu: $(OBJS)
- X $(CC) $(CFLAGS) -o $@ $(OBJS)
- END_OF_Makefile
- if test 104 -ne `wc -c <Makefile`; then
- echo shar: \"Makefile\" unpacked with wrong size!
- fi
- # end of overwriting check
- fi
- echo shar: End of shell archive.
- exit 0
-
-